﻿/** \file
* \$Rev: 183 $
* 
* \$Date: 2010-04-14 00:34:38 +0000 (Wed, 14 Apr 2010) $
*
* \$URL: http://chorus-twitter.googlecode.com/svn/trunk/src/net/QueryParameters.cs $
*/

using System;
using System.Collections.Generic;

namespace chorus.net
{
	/// <summary>
	/// An abstract query parameter used to construct a query string.
	/// </summary>
	public abstract class AbstractQueryParameter
	{
		/// <summary>The name of the parameter.</summary>
		public readonly string name;
		/// <summary>Whether the parameter is set.</summary>
		protected bool isset = false;
		/// <summary>Whether the parameter is set.</summary>
		public bool IsSet { get { return isset; } }
		/// <summary>The parameter value, as converted to a string.</summary>
		public abstract string StringVal { get; }

		/// <summary>The constructor.</summary>
		/// <param name="name">The name of the parameter.</param>
		public AbstractQueryParameter(string name) { this.name = name; }
	}

	/// <summary>
	/// A query parameter with a generic value type.
	/// </summary>
	/// <typeparam name="ParmType">The parameter value type.</typeparam>
	public class QueryParameter<ParmType> : AbstractQueryParameter
	{
		/// <summary>The parameter value.</summary>
		ParmType val;
		/// <summary>The parameter value. Keeps track of if it's been set.</summary>
		public ParmType Val
		{
			get { return val; }
			set { isset = true; val = value; }
		}
		/// <summary>The parameter value, as converted to a string.</summary>
		public override string StringVal { get { return val.ToString(); } }

		/// <summary>The constructor.</summary>
		/// <param name="name">The name of the parameter.</param>
		public QueryParameter(string name) : base(name) { }
	}

	/// <summary>
	/// A set of query parameters.
	/// </summary>
	public abstract class QueryParameters
	{
		/// <summary>Populate the given list with these parameters.</summary>
		/// <param name="parms">The list to populate.</param>
		public abstract void Populate(List<AbstractQueryParameter> parms);
	}

	/// <summary>
	/// Typical Twitter pagination parameters.
	/// </summary>
	public class PagedParameters : QueryParameters
	{
		/// <summary>The oldest ID in the list to fetch.</summary>
		public QueryParameter<ulong> since_id = new QueryParameter<ulong>("since_id");
		/// <summary>The newest ID in the list to fetch.</summary>
		public QueryParameter<ulong> max_id = new QueryParameter<ulong>("max_id");
		/// <summary>The number of direct messages to fetch.</summary>
		public QueryParameter<uint> count = new QueryParameter<uint>("count");
		/// <summary>The page number associated with this request.</summary>
		public QueryParameter<uint> page = new QueryParameter<uint>("page");

		/// <summary>Populate the given list with these parameters.</summary>
		/// <param name="parms">The list to populate.</param>
		public override void Populate(List<AbstractQueryParameter> parms)
		{
			parms.Add(since_id);
			parms.Add(max_id);
			parms.Add(count);
			parms.Add(page);
		}
	}

	/// <summary>
	/// Parameters to specify a user.
	/// </summary>
	public class UserIDParameters : QueryParameters
	{
		/// <summary>The user ID.</summary>
		public QueryParameter<ulong> user_id = new QueryParameter<ulong>("user_id");
		/// <summary>The user screen name.</summary>
		public QueryParameter<string> screen_name = new QueryParameter<string>("screen_name");

		/// <summary>Populate the given list with these parameters.</summary>
		/// <param name="parms">The list to populate.</param>
		public override void Populate(List<AbstractQueryParameter> parms)
		{
			parms.Add(user_id);
			parms.Add(screen_name);
		}
	}
}
